package public

import (
	"server/game/cache"
	"server/game/define/helper"
	"server/game/itypes"
	"server/game/model"
	"server/share/config"

	"github.com/hwcer/cosgo"
	"github.com/hwcer/cosgo/registry"
	"github.com/hwcer/updater"
	"github.com/hwcer/yyds/context"
	"github.com/hwcer/yyds/errors"
	"github.com/hwcer/yyds/players"
	"github.com/hwcer/yyds/players/player"
)

func init() {
	i := &Hook{}
	Register(i)
	cosgo.On(cosgo.EventTypLoaded, func() error {
		players.Listen(config.Data.Events.BattleStage, func(u *updater.Updater, vs ...int32) {
			if len(vs) > 0 && vs[0] > 0 {
				doc := u.Document(config.ITypeRole)
				role := doc.Any().(*model.Role)
				v := role.GetHook()
				_ = i.settlement(u, v, vs[0], true)
			}
		})
		return nil
	})
}

// 抽卡 协议兼容模式 后续使用 系统自带 /gacha/* 相关
type Hook struct {
}

func (this *Hook) Caller(node *registry.Node, handle *context.Context) interface{} {
	f := node.Method().(func(*Hook, *context.Context) interface{})
	return f(this, handle)
}

func (this *Hook) Reward(p *player.Player, role *model.Role, hk *model.RoleHook) (res map[int32]int32, err error) {
	battlePoint := role.BattlePoint
	if battlePoint == 0 {
		battlePoint = 1
	}
	challenge := config.GetChallenge(battlePoint)
	if challenge == nil {
		return nil, errors.Errorf(0, "config challenge not exist : %d", battlePoint)
	}
	if hk.Value > challenge.Limit {
		hk.Value = challenge.Limit
	}
	num := hk.Value / challenge.Frequency
	if num <= 0 {
		return nil, nil
	}

	items := helper.AddItemsFromFormula(role.BattlePoint, num, challenge.OfflineReward)
	for k, v := range items {
		p.Add(k, v)
	}
	//积分
	//i := int32(1)
	//for {
	//	hookScore := config.Data.HookScore[i]
	//	if hookScore == nil || hk.Score < hookScore.Score {
	//		break
	//	}
	//	n := hk.Score / hookScore.Score
	//	p.AddItems(hookScore.Items, n)
	//	hk.Score -= n * hookScore.Score
	//	i += 1
	//}
	hk.Value -= num * challenge.Frequency

	return items, nil
}

/**
 * @name init_hook
 * 挂机初始化 废弃
 */
func (this *Hook) Init_hook(c *context.Context) interface{} {
	doc := cache.GetRole(c.Player.Updater)
	role := doc.All()

	if role.Hook == nil {
		doc.Set("hook", &model.RoleHook{Time: c.Unix()})
	}
	return true
}

/**
 * @name claim_hook
 * 获取挂机奖励
 */

func (this *Hook) Claim_hook(c *context.Context) interface{} {
	doc := cache.GetRole(c.Player.Updater)
	role := doc.All()
	hk := role.GetHook()
	if err := this.settlement(c.Player.Updater, hk, role.BattlePoint, false); err != nil {
		return err
	}
	if _, err := this.Reward(c.Player, role, hk); err != nil {
		return err
	}
	doc.Set("hook", hk)
	c.Player.Emit(config.Data.Events.OfflineRewardGet, 1)
	return true
}

/**
 * @name buy_hook_reward
 * 购买挂机奖励
 * @tip 加速记录为 daily.hookSNum
 */

func (this *Hook) Buy_hook_reward(c *context.Context) interface{} {

	doc := cache.GetRole(c.Player.Updater)
	role := doc.All()
	//hk := role.GetHook()
	daily := itypes.Daily.Handle(c.Player.Updater)
	hookSNum := daily.GetInt32(config.Data.DailyKey.HookSNum)

	hookSpeed := config.Data.HookSpeed[hookSNum+1]
	if hookSpeed == nil {
		return c.Error("购买加速次数不足")
	}

	//if err := this.settlement(c.Player.Updater, hk, role.BattlePoint, false); err != nil {
	//	return err
	//}
	c.Player.SubItems(hookSpeed.Sub)
	challenge := config.GetChallenge(role.BattlePoint)
	if challenge == nil {
		return c.Error("请先通过战区")
	}
	hk := &model.RoleHook{}
	hk.Value = hookSpeed.Val
	if err := this.settlement(c.Player.Updater, hk, role.BattlePoint, false); err != nil {
		return err
	}
	if _, err := this.Reward(c.Player, role, hk); err != nil {
		return err
	}
	//doc.Set("hook", hk)
	c.Player.Emit(config.Data.Events.HookSNum, 1)
	return true
}

func (this *Hook) settlement(u *updater.Updater, hk *model.RoleHook, stage int32, autoSave bool) (err error) {
	doc := cache.GetRole(u)
	//if stage == 0 {
	//	stage = 1
	//}

	defer func() {
		if err == nil && autoSave {
			doc.Set("hook", hk)
		}
	}()

	//challenge := config.GetChallenge(stage)
	//if challenge == nil {
	//	return errors.Errorf(0, "config challenge not exist : %d", stage)
	//}
	now := u.Unix()
	if hk.Time == 0 {
		hk.Time = now
	}
	subTime := now - hk.Time
	//frequency := int64(challenge.Frequency)

	//var n int64
	//if limitTime := int64(challenge.Limit - hk.Value*challenge.Frequency); subTime >= limitTime {
	//	subTime = limitTime
	//	hk.Time = u.Unix()
	//	if subTime >= frequency {
	//		n = subTime / frequency
	//	}
	//} else if subTime >= frequency {
	//	n = subTime / frequency
	//	hk.Time += n * frequency
	//} else {
	//	return nil
	//}
	hk.Time = now
	hk.Value += int32(subTime)
	return nil
}
